//
//  ESNavigationController.m
//  EasyStyle
//
//  Created by FK on 15/12/11.
//  Copyright © 2015年 FK. All rights reserved.
//

#import "ESNavigationController.h"
#import <QuartzCore/QuartzCore.h>
#import "UIImage+ESColor.h"

#define StatusBarOffset 0
#define BeginScaleValue (0.95f)
#define BeginAplhaValue (.5f)
#define BeginxPosValue (0.7f)

static BOOL isAnimating = NO;

@interface ESNavigationController ()

@property (nonatomic, strong) UIPanGestureRecognizer *panGesture;
@property (nonatomic, strong) UIView *preScreenImageView;
@property (nonatomic, strong) UIImageView *leftShadowImageView;
@property (nonatomic, strong) NSMutableArray *imagesArray;
@property (nonatomic, assign) BOOL shouldReceiveTouch;
@property (nonatomic, strong) NSMutableArray *classesArray;

@end

@implementation ESNavigationController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    if ([UIDevice currentDevice].systemVersion.floatValue<7.0) {
        
        NSDictionary *titleTextAttributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                             [UIColor colorWithHex:@"333333"], UITextAttributeTextColor,
                                             [UIFont boldSystemFontOfSize:18], UITextAttributeFont,
                                             [NSValue valueWithUIOffset:UIOffsetMake(0,0)],UITextAttributeTextShadowOffset,
                                             [UIColor clearColor],UITextAttributeTextShadowColor,
                                             nil];
        [self.navigationBar setTitleTextAttributes:titleTextAttributes];
        
        [self.navigationBar setBackgroundImage:[UIImage createImageWithColor:[UIColor colorWithHex:@"f7f7f7"]] forBarMetrics:UIBarMetricsDefault];
        
        self.navigationBar.shadowImage = [UIImage createImageWithColor:[UIColor colorWithHex:@"c7c7c7"]];
    }
    
    if ([self.navigationBar respondsToSelector:@selector(setBarTintColor:)]) {
        [self.navigationBar setBarTintColor:[UIColor colorWithWhite:0xf5*1.0/255 alpha:1]];
    }
    
    self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onPanGesture:)];
    
    UIImage *shadowImageView = [[UIImage imageNamed:@"leftShadow.png"] resizableImageWithCapInsets:UIEdgeInsetsZero];
    
    self.leftShadowImageView = [[UIImageView alloc] initWithImage:shadowImageView];
    self.leftShadowImageView.frame = CGRectMake(-7, 0, 7, [UIScreen mainScreen].bounds.size.height);
    
    [self.view addGestureRecognizer:self.panGesture];
    
    self.panGesture.delegate = self;
    
    self.imagesArray = [NSMutableArray array];
    
    self.classesArray = [NSMutableArray array];
    
    self.shouldReceiveTouch = NO;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (UIViewController *)childViewControllerForStatusBarStyle{
    return self.topViewController;
}


- (void)dealloc{
    [self.view removeGestureRecognizer:self.panGesture];
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
    
    int statusBarOffset = StatusBarOffset;
    
    if ([UIDevice currentDevice].systemVersion.floatValue>6.99f) {
        statusBarOffset = 0;
    }
    
    if (isAnimating == YES) {
        return ;
    }
    else{
        isAnimating = YES;
    }
    
    if ([self.viewControllers count] > 0) {
        [self saveScreenShot];
    }
    [super pushViewController:viewController animated:NO];
    
    self.shouldReceiveTouch = YES;
    
    if (!animated) {
        
        if (self.preScreenImageView != nil) {
            [self.preScreenImageView removeFromSuperview];
            self.preScreenImageView = nil;
        }
        
        isAnimating = NO;
        return;
    }
    
    __block CGRect currentFrame = self.view.frame;
    currentFrame.origin.x = ScreenWidth;
    
    self.view.frame = currentFrame;
    
    [self.preScreenImageView removeFromSuperview];
    
    self.preScreenImageView = nil;
    self.preScreenImageView = [self screenImageViewAtIndex:[self.imagesArray count]-1];
    self.preScreenImageView.frame = CGRectMake(0, statusBarOffset, ScreenWidth, [UIScreen mainScreen].bounds.size.height-statusBarOffset);
    self.preScreenImageView.transform = CGAffineTransformIdentity;
    self.preScreenImageView.alpha = 1;
    
    [self.view.superview insertSubview:self.preScreenImageView belowSubview:self.view];
    
    [UIView animateWithDuration:.35 animations:^{
        
        currentFrame.origin.x= 0;
        self.view.frame = currentFrame;
        
        self.preScreenImageView.transform = CGAffineTransformMakeTranslation(-BeginxPosValue *ScreenWidth, 0);
        self.preScreenImageView.alpha = BeginAplhaValue;
        
    } completion:^(BOOL finished){
        [self.preScreenImageView removeFromSuperview];
        self.preScreenImageView  = nil;
        isAnimating = NO;
    }];
    
}

- (UIViewController *)popViewControllerAnimated:(BOOL)animated{
    
    int statusBarOffset = StatusBarOffset;
    
    if ([UIDevice currentDevice].systemVersion.floatValue>6.99f) {
        statusBarOffset = 0;
    }
    
    if (self.viewControllers.count == 1) {
        
        return nil;
    }
    
    if (isAnimating == YES) {
        return nil;
    }
    else{
        isAnimating = YES;
    }
    
    if (self.viewControllers.count == 2){
        self.shouldReceiveTouch = NO;
    }
    
    if (!animated) {
        
        
        if (self.preScreenImageView != nil) {
            [self.preScreenImageView removeFromSuperview];
            self.preScreenImageView = nil;
        }
        
        [self.imagesArray removeLastObject];
        
        isAnimating = NO;
        
        return [super popViewControllerAnimated:NO];
        
    }
    
    __block CGRect currentFrame = self.view.frame;
    currentFrame.origin.x = ScreenWidth;
    
    [self.preScreenImageView removeFromSuperview];
    
    self.preScreenImageView = nil;
    self.preScreenImageView = [self screenImageViewAtIndex:[self.imagesArray count]-1];
    self.preScreenImageView.frame = CGRectMake(0, statusBarOffset, ScreenWidth, [UIScreen mainScreen].bounds.size.height-statusBarOffset);
    self.preScreenImageView.transform = CGAffineTransformMakeTranslation(-BeginxPosValue *ScreenWidth, 0);
    self.preScreenImageView.alpha = BeginAplhaValue;
    
    [self.view.superview insertSubview:self.preScreenImageView belowSubview:self.view];
    
    UIViewController *retVC =  [self.viewControllers objectAtIndex:self.viewControllers.count - 2];
    
    [UIView animateWithDuration:.35 animations:^{
        
        self.view.frame = currentFrame;
        self.preScreenImageView.transform = CGAffineTransformIdentity;
        self.preScreenImageView.alpha = 1.0;
        
    } completion:^(BOOL finished){
        
        
        [self.preScreenImageView removeFromSuperview];
        self.preScreenImageView = nil;
        [self.imagesArray removeLastObject];
        
        currentFrame.origin.x= 0;
        self.view.frame = currentFrame;
        [super popViewControllerAnimated:NO];
        
        isAnimating = NO;
    }];
    
    return retVC;
    
    
}


- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated{
    
    int statusBarOffset = StatusBarOffset;
    
    if ([UIDevice currentDevice].systemVersion.floatValue>6.99f) {
        statusBarOffset = 0;
    }
    
    if (self.viewControllers.count == 1) {
        return nil;
    }
    
    if (isAnimating == YES) {
        return nil;
    }
    else{
        isAnimating = YES;
    }
    
    self.shouldReceiveTouch = NO;
    
    if (!animated) {
        if (self.preScreenImageView != nil) {
            [self.preScreenImageView removeFromSuperview];
            self.preScreenImageView = nil;
        }
        
        [self.imagesArray removeAllObjects];
        
        isAnimating = NO;
        
        return [super popToRootViewControllerAnimated:NO];
        
    }
    
    int vcIdx = [self.viewControllers indexOfObject:self.visibleViewController];
    
    __block CGRect currentFrame = self.view.frame;
    currentFrame.origin.x = ScreenWidth;
    
    [self.preScreenImageView removeFromSuperview];
    
    self.preScreenImageView = nil;
    self.preScreenImageView =  [self screenImageViewAtIndex:self.imagesArray.count-vcIdx];
    self.preScreenImageView.frame = CGRectMake(0, statusBarOffset, ScreenWidth, [UIScreen mainScreen].bounds.size.height-statusBarOffset);
    self.preScreenImageView.transform = CGAffineTransformMakeTranslation(-BeginxPosValue *ScreenWidth, 0);
    self.preScreenImageView.alpha = BeginAplhaValue;
    
    [self.view.superview insertSubview:self.preScreenImageView belowSubview:self.view];
    
    
    NSMutableArray *retArray = [NSMutableArray array];
    
    for (int idx = 1; idx < self.viewControllers.count; idx++) {
        [retArray addObject:[self.viewControllers objectAtIndex:idx]];
    }
    
    
    [UIView animateWithDuration:.35 animations:^{
        
        self.view.frame = currentFrame;
        self.preScreenImageView.transform = CGAffineTransformIdentity;
        self.preScreenImageView.alpha = 1.0;
        
    } completion:^(BOOL finished){
        
        [self.preScreenImageView removeFromSuperview];
        self.preScreenImageView = nil;
        [self.imagesArray removeAllObjects];
        
        currentFrame.origin.x= 0;
        self.view.frame = currentFrame;
        [super popToRootViewControllerAnimated:NO];
        
        isAnimating = NO;
    }];
    
    
    return retArray;
}


- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated{
    
    int statusBarOffset = StatusBarOffset;
    
    if ([UIDevice currentDevice].systemVersion.floatValue>6.99f) {
        statusBarOffset = 0;
    }
    
    
    if (self.viewControllers.count == 1|| ![self.viewControllers containsObject:viewController] || self.visibleViewController == viewController) {
        return nil;
    }
    
    if (isAnimating == YES) {
        return nil;
    }
    else{
        isAnimating = YES;
    }
    
    if (self.viewControllers[0] == viewController) {
        self.shouldReceiveTouch = NO;
    }
    
    NSUInteger vcIdx = [self.viewControllers indexOfObject:viewController];
    
    if (!animated) {
        if (self.preScreenImageView != nil) {
            [self.preScreenImageView removeFromSuperview];
            self.preScreenImageView = nil;
        }
        
        NSRange range = NSMakeRange(vcIdx, self.imagesArray.count-vcIdx);
        [self.imagesArray removeObjectsInRange:range];
        
        isAnimating = NO;
        
        return [super popToViewController:viewController animated:NO];
        
    }
    
    
    __block CGRect currentFrame = self.view.frame;
    currentFrame.origin.x = ScreenWidth;
    
    [self.preScreenImageView removeFromSuperview];
    
    self.preScreenImageView = nil;
    self.preScreenImageView = [self screenImageViewAtIndex:vcIdx];
    self.preScreenImageView.frame = CGRectMake(0, statusBarOffset, ScreenWidth, [UIScreen mainScreen].bounds.size.height-statusBarOffset);
    self.preScreenImageView.transform = CGAffineTransformMakeTranslation(-BeginxPosValue *ScreenWidth, 0);
    self.preScreenImageView.alpha = BeginAplhaValue;
    
    [self.view.superview insertSubview:self.preScreenImageView belowSubview:self.view];
    
    
    NSMutableArray *retArray = [NSMutableArray array];
    
    for (NSUInteger idx = vcIdx + 1; idx < self.viewControllers.count; idx++) {
        [retArray addObject:[self.viewControllers objectAtIndex:idx]];
    }
    
    
    [UIView animateWithDuration:.35 animations:^{
        
        self.view.frame = currentFrame;
        self.preScreenImageView.transform = CGAffineTransformIdentity;
        self.preScreenImageView.alpha = 1.0;
        
    } completion:^(BOOL finished){
        
        [self.preScreenImageView removeFromSuperview];
        self.preScreenImageView = nil;
        
        NSRange range = NSMakeRange(vcIdx, self.imagesArray.count-vcIdx);
        [self.imagesArray removeObjectsInRange:range];
        
        currentFrame.origin.x= 0;
        self.view.frame = currentFrame;
        [super popToViewController:viewController animated:NO];
        
        isAnimating = NO;
    }];
    
    
    return retArray;
    
}


- (UIView *)screenImageViewAtIndex:(NSUInteger)index{
    if (index > [self.imagesArray count] - 1) {
        return nil;
    }
    return [self.imagesArray[index] isKindOfClass:[UIImage class]]?[[UIImageView alloc] initWithImage:self.imagesArray[index]]:self.imagesArray[index];
}


- (void)onPanGesture:(UIPanGestureRecognizer *)panGesture{
    
    int statusBarOffset = StatusBarOffset;
    
    if ([UIDevice currentDevice].systemVersion.floatValue>6.99f) {
        statusBarOffset = 0;
    }
    
    if (self.viewControllers.count <= 1) {
        
        return;
    }
    
    
    
    CGPoint point = [panGesture translationInView:self.view.superview];
    
    if (point.x<0) {
        
        CGRect currentFrame = self.view.frame;
        
        if (currentFrame.origin.x == 0) {
            return;
        }
        
        currentFrame.origin.x = 0;
        
        [UIView animateWithDuration:.2 animations:^{
            self.view.frame = currentFrame;
            
            self.preScreenImageView.transform = CGAffineTransformMakeTranslation(-BeginxPosValue *ScreenWidth, 0);
            self.preScreenImageView.alpha = BeginAplhaValue;
            
        } completion:^(BOOL finisehd){
            ;
            
        }];
        
        NSLog(@"<0");
        return;
    }
    
    
    CGRect frame = self.view.frame;
    frame.origin.x = point.x;
    float scaleFactor = point.x/ScreenWidth;
    
    float xVelocity = [panGesture velocityInView:self.view.superview].x;
    
    switch (panGesture.state) {
        case UIGestureRecognizerStateBegan:
            // NSLog(@"UIGestureRecognizerStateBegan");
            [self.preScreenImageView removeFromSuperview];
            
            self.preScreenImageView = nil;
            self.preScreenImageView = [self screenImageViewAtIndex:[self.imagesArray count]-1];
            self.preScreenImageView.frame = CGRectMake(0, statusBarOffset, ScreenWidth, [UIScreen mainScreen].bounds.size.height-statusBarOffset);
            self.preScreenImageView.transform = CGAffineTransformMakeTranslation(-BeginxPosValue *ScreenWidth, 0);
            self.preScreenImageView.alpha = BeginAplhaValue;
            
            [self.view.superview insertSubview:self.preScreenImageView belowSubview:self.view];
            
            
            break;
            
        case UIGestureRecognizerStateChanged:
            //NSLog(@"UIGestureRecognizerStateChanged");
            if (self.preScreenImageView == nil) {
                self.preScreenImageView = [self screenImageViewAtIndex:[self.imagesArray count]-1];;
                self.preScreenImageView.frame = CGRectMake(0, statusBarOffset, ScreenWidth, [UIScreen mainScreen].bounds.size.height-statusBarOffset);
                [self.view.superview insertSubview:self.preScreenImageView belowSubview:self.view];
            }
            
            self.preScreenImageView.transform = CGAffineTransformMakeTranslation(-BeginxPosValue*ScreenWidth*(1-scaleFactor),0);
            self.preScreenImageView.alpha = BeginAplhaValue + (1- BeginAplhaValue) * scaleFactor;
            self.view.frame = frame;
            
            break;
        case UIGestureRecognizerStateEnded:
        case UIGestureRecognizerStateCancelled:
        case UIGestureRecognizerStateFailed:
            //NSLog(@"UIGestureRecognizerStateEnded");
            
            if ((point.x<(ScreenWidth/2)-90) || (xVelocity<-1500)) {
                
                CGRect currentFrame = self.view.frame;
                currentFrame.origin.x = 0;
                
                [UIView animateWithDuration:.15 animations:^{
                    
                    self.view.frame = currentFrame;
                    self.preScreenImageView.transform = CGAffineTransformMakeTranslation(-BeginxPosValue *ScreenWidth, 0);
                    self.preScreenImageView.alpha = BeginAplhaValue;
                    
                } completion:^(BOOL finished){
                    
                    [self.preScreenImageView removeFromSuperview];
                    self.preScreenImageView = nil;
                    
                }];
            }
            else if ((point.x>=(ScreenWidth/2)-90) || (xVelocity>1500)){
                __block CGRect currentFrame = self.view.frame;
                currentFrame.origin.x = ScreenWidth;
                
                [UIView animateWithDuration:.2 animations:^{
                    
                    self.view.frame = currentFrame;
                    self.preScreenImageView.transform = CGAffineTransformIdentity;
                    self.preScreenImageView.alpha = 1.0;
                    
                } completion:^(BOOL finished){
                    [self.preScreenImageView removeFromSuperview];
                    self.preScreenImageView = nil;
                    [self.imagesArray removeLastObject];
                    currentFrame.origin.x= 0;
                    self.view.frame = currentFrame;
                    [super popViewControllerAnimated:NO];
                    
                }];
            }
            
            break;
        default:
            break;
    }
}

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    
    if (gestureRecognizer == self.panGesture) {
        
        for (Class aClass in self.classesArray) {
            if ([touch.view isKindOfClass:aClass]) {
                return NO;
            }
            if ([self.topViewController isKindOfClass:aClass]) {
                return NO;
            }
        }
        
        if ([touch.view isKindOfClass:[UISlider class]] || self.viewControllers.count <= 1 ) {
            return NO;
        }
        
    }
    return self.shouldReceiveTouch;
}


- (void)saveScreenShot{
    
    
    int statusBarOffset = StatusBarOffset;
    
    if ([UIDevice currentDevice].systemVersion.floatValue>6.99f) {
        statusBarOffset = 0;
    }
    
    UIImage *screenShootImage = nil;
    CGSize size = [UIScreen mainScreen].bounds.size;
    
    if ([UIDevice currentDevice].systemVersion.floatValue<6.99) {
        size.height -= statusBarOffset;
    }
    
    UIGraphicsBeginImageContextWithOptions(size, NO,0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    
    if ([UIDevice currentDevice].systemVersion.floatValue<7.0) {
        
        
        [self.view.layer renderInContext:context];
        
    }else{
        
        CGContextTranslateCTM(context, 0, -statusBarOffset);
        
        for(UIView *subview in self.view.subviews)
        {
            [subview drawViewHierarchyInRect:subview.bounds afterScreenUpdates:YES];
        }
        
    }
    CGContextRestoreGState(context);
    
    screenShootImage = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    
    [self.imagesArray addObject:screenShootImage];
}

- (void)registerClass:(Class)aClass{
    
    if (![self.classesArray containsObject:aClass]) {
        [self.classesArray addObject:aClass];
    }
}

@end
